import { Modal as ModalAntd, ModalFuncProps, ModalProps as ModalPropsAntd } from 'antd';
import {
    SyncOutlined,
} from '@ant-design/icons';
import { t } from 'i18next';
import React, { Component, ReactNode, useMemo, useState } from 'react';
import styled from 'styled-components';
import { theme } from '../theme';
import styles from './styles.module.css';


interface TitleProps {
    title: string
}

interface ContentProps {
    icon?: ReactNode;
    content?: string | ReactNode;
    html?: string;
}

interface FooterProps {
    okText?: string | ReactNode;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    okClick?: (...args: any[]) => void;
    cancelText?: string | ReactNode;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    cancelClick?: (...args: any[]) => void;
    custom?: ReactNode;
    isVertical?: boolean;
    isLodingOk?: boolean;
}

const Title = styled.div`
    color: ${theme.text.modal_title};
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 1.25rem;
    font-weight: 500;
    height: 1.75rem;
    background-color: transparent;
`

const TitleBox: React.FC<TitleProps> = ({ title }) => {
    return <Title>{title}</Title>
}

const IconBox = styled.div`
    position: relative;
`

const IconText = styled.span`
    position: absolute;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    left: 17px;
    top: 27px;
    color: ${theme.text.normal};
    font-size: 11px;
`

const Content = styled.div<{ $hasIcon?: number }>`
    height: 9.25rem;
    width: 100%;
    padding-top: ${({ $hasIcon }) => $hasIcon ? '.25rem' : '1.25rem'};
    box-sizing: border-box;
    .custom-modal-content {
        height: 100%;
        overflow-y: auto;
        width: 100%;
        padding: ${({ $hasIcon }) => $hasIcon ? '0 .875rem 0' : '0 .625rem 0'};
        box-sizing: border-box;
        display: flex;
        flex-direction: column;
        align-items: ${({ $hasIcon }) => $hasIcon ? 'center' : 'unset'};
        .custom-modal-content-text {
            font-size: 1rem;
            margin-top: ${({ $hasIcon }) => $hasIcon ? '.9375rem' : '0'};
        }
        .custom-modal-content-pre {
            font-size: 1rem;
            margin: 0;
            white-space: pre-line;
        };
    }
`

const ContentBox: React.FC<ContentProps & { isSystem?: boolean }> = ({ icon, content, isSystem, html }) => {
    return <Content $hasIcon={icon ? 1 : 0}>
        <div className="custom-modal-content">
            {icon}
            {content && !isSystem && <div className="custom-modal-content-text">{content}</div>}
            {content && isSystem && <pre className="custom-modal-content-text custom-modal-content-pre">{content}</pre>}
            {html && <span dangerouslySetInnerHTML={{ __html: html }} />}
        </div>
    </Content>
}

const Footer = styled.div<{ $two?: number, $isV?: number }>`
    height: ${({ $isV }) => $isV ? '6.5rem' : '3rem'};;
    width: 100%;
    margin-top: 1.875rem;
    display: flex;
    align-items: center;
    flex-direction: ${({ $isV }) => $isV ? 'column-reverse' : 'row'};
    justify-content: ${({ $two }) => $two ? 'space-between' : 'center'};
    padding: 0 1.5rem;
    box-sizing: border-box;
`

const Button = styled.div<{ width?: string, $background?: string, $borderColor?: string, $color?: string, $disable?: number }>`
    width: ${({ width }) => width || '13.25rem'};
    height: 2.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: ${({ $background }) => $background || theme.modal.confirm_bg};
    border-radius: 1rem;
    color: ${({ $color }) => $color || theme.text.normal};
    border: ${({ $borderColor }) => $borderColor ? `1px solid ${$borderColor}` : undefined};
    pointer-events: ${({ $disable }) => $disable ? 'none' : 'all'};
`

const FooterBox: React.FC<FooterProps & { isSystem?: boolean }> = ({ okText, okClick, cancelText, cancelClick, isVertical, custom, isSystem, isLodingOk }) => {
    const two = useMemo(() => okText && cancelText ? 1 : 0, [okText, cancelText])
    const [loading, setLoading] = useState(false)

    const handleOk: React.MouseEventHandler<HTMLDivElement> = async (event) => {
        isLodingOk && setLoading(true)
        await okClick?.(event)
        setLoading(false)
    }

    return <Footer
        $two={two}
        $isV={Number(Boolean(isVertical))}
    >
        {custom ? custom :
            <>
                {cancelText &&
                    <Button
                        $background={theme.background.base}
                        width={two ? (isVertical ? '100%' : '5.25rem') : undefined}
                        onClick={cancelClick}
                        $borderColor={isSystem ? theme.background.button : theme.modal.cancel_border}
                        $color={isSystem ? theme.background.button : theme.modal.cancel_color}
                    >
                        {cancelText}
                    </Button>
                }
                {okText &&
                    <Button
                        $disable={Number(loading)}
                        $background={isSystem ? theme.background.button : undefined}
                        width={two ? (isVertical ? '100%' : '5.25rem') : undefined}
                        onClick={handleOk}
                    >
                        {(loading) && <SyncOutlined
                            spin
                            style={{ marginRight: '4px' }}
                        />}
                        {okText}
                    </Button>
                }
            </>
        }
    </Footer>
}

type Override<P, S> = Omit<P, keyof S> & S;
type ModalProps = Override<ModalFuncProps, {
    title?: string | ReactNode;
    content?: ContentProps | string;
    footer?: FooterProps;
    isLodingOk?: boolean;
    height?: string;
}>


type ModalComponetProps = Override<ModalPropsAntd, {
    title?: string | ReactNode;
    content?: ContentProps | string;
    footer?: FooterProps;
    isSystem?: boolean;
    isLodingOk?: boolean;
    height?: string;
}>


class Modal extends Component<ModalComponetProps, object, unknown> {

    private static lastModel?: ReturnType<typeof ModalAntd.info>

    private static base(props: ModalProps, isSystem?: boolean) {
        const { title, width, height, footer, content, okText, cancelText, onOk, onCancel, isLodingOk, ...other } = props;
        const contentProps = (typeof content === 'string' ? { content } : content) || {}

        const footerProps: FooterProps = {
            okText: footer?.okText || okText,
            okClick: footer?.okClick || onOk,
            cancelText: footer?.cancelText || cancelText,
            cancelClick: footer?.cancelClick || onCancel,
            isVertical: footer?.isVertical || false,
            custom: footer?.custom,
            isLodingOk,
        }

        this.lastModel?.destroy()
        this.lastModel = undefined

        const modal = ModalAntd[props.type || 'confirm']({
            title: typeof title === 'string' ? <TitleBox title={title} /> : title,
            width: width || '19.25rem',
            style: {
                height: height || '18.875rem',
                background: '#1b314c',
                borderRadius: '10px'
                // background: `url(${isSystem ? IconModalSystem : IconModalNormal}) no-repeat center center`,
            },
            icon: <></>,
            footer: <FooterBox
                {...footerProps}
                isSystem={isSystem}
            />,
            content: <ContentBox
                {...contentProps}
                isSystem={isSystem}
            />,
            getContainer: () => document.getElementById('ele_modal') || document.body,
            className: styles.custom,
            ...other,
            centered: true,
        })

        this.lastModel = modal
        return {
            ...modal,
            destroy: () => {
                this.lastModel = undefined;
                modal.destroy()
            }
        }
    }

    static info(props: ModalProps) {
        return this.base({
            ...props,
            type: 'info'
        })
    }

    static success(props: ModalProps) {
        return this.base({
            ...props,
            type: 'success'
        })
    }

    static error(props: ModalProps) {
        const modal = this.base({
            type: 'error',
            footer: {
                okText: t('common.confirm'),
                okClick: () => modal.destroy()
            },
            ...props,
        })
        return modal
    }

    static confirm(props: ModalProps) {
        return this.base({
            ...props,
            type: 'confirm'
        })
    }

    static system(props: ModalProps) {
        return this.base({
            ...props,
            type: 'info'
        }, true)
    }

    static upgrade(props: ModalProps & { iconText?: string }) {
        const { content, iconText, footer } = props
        const c = typeof content === 'string' ? { content } : content || {}
        return this.base({
            ...props,
            type: 'info',
            content: {
                ...c,
                icon: <IconBox>
                    <img
                        width="88px"
                        // src={IconUpgrade}
                        alt="upgrade"
                    />
                    {iconText && <IconText>{iconText}</IconText>}
                </IconBox>
            },
            footer: {
                ...footer,
                okText: t('common.check')

            }
        })
    }

    static destroyAll() {
        ModalAntd.destroyAll();
    }

    render() {
        const { title, width, height, footer, wrapClassName, content, style, okText, cancelText, onOk, onCancel, isSystem, modalRender, isLodingOk, ...other } = this.props;
        const contentProps = (typeof content === 'string' ? { content } : content) || {}
        const footerProps: FooterProps = {
            okText: footer?.okText || okText,
            okClick: footer?.okClick || onOk,
            cancelText: footer?.cancelText || cancelText,
            cancelClick: footer?.cancelClick || onCancel,
            custom: footer?.custom,
            isLodingOk
        }

        return modalRender ?
            <ModalAntd
                open={this.props.open}
                wrapClassName={wrapClassName}
                modalRender={modalRender}
                style={style}
                width={width}
                getContainer={() => document.getElementById('ele_modal') || document.body}
                {...other}
            >
                {this.props.children}
            </ModalAntd> :
            <ModalAntd
                getContainer={() => document.getElementById('ele_modal') || document.body}
                wrapClassName={styles.custom}
                open={this.props.open}
                title={typeof title === 'string' ? <TitleBox title={title} /> : title}
                width={width || '19.25rem'}
                centered={true}
                closeIcon={false}
                style={{
                    height: height || '18.875rem',
                    // background: `url(${isSystem ? IconModalSystem : IconModalNormal}) no-repeat center center`,
                    ...style
                }}
                footer={<FooterBox
                    {...footerProps}
                    isSystem={isSystem}
                />}
                {...other}
            >
                <ContentBox
                    {...contentProps}
                    isSystem={isSystem}
                />
            </ModalAntd>
    }
}

export default Modal